import java.io.*;
import java.util.ArrayList;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.NamingException;
   
public class Interface extends HttpServlet {
    
    public static final String NEWLINE = "\n";
    public static final String TAB = "\t";
    //
	private Sessions sessions = new Sessions();
	private HttpServletRequest request;
	private HttpServletResponse response;
	PrintWriter out;
	
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		this.request=request;
		this.response=response;
		//response.setContentType("text/xml");
		this.out = response.getWriter();
		String todo = request.getParameter("todo");
		if(todo.equals("conectar"))
			conectar();
		if(todo.equals("desconectar"))
			desconectar();
		if(todo.equals("download"))
			download();
		if(todo.equals("upload"))
			upload();
		if(todo.equals("listar"))
			listar();
		if(todo.equals("mover"))
			mover();
		if(todo.equals("deletar"))
			deletar();
		if(todo.equals("mkdir"))
			mkdir();
		if(todo.equals("copiar"))
			copiar();
		if(todo.equals("atualizar"))
			atualizar();
		if(todo.equals("versao"))
			versao();
		if(todo.equals("versaoDisco"))
			versaoDisco();
		if(todo.equals("fudeu"))
		    out.print("lascou");
	}

	boolean isAutenticated(){
		try{
			String token=request.getParameter("token");
			if (sessions.isValid(token))
					return true;
			return false;
		}
		catch(Exception e){
			out.print("lascou");
		}
		return false;
	}

	public void conectar(){ //TODO
		String user=request.getParameter("user");
		String password=request.getParameter("password");
		String homePath="";
		int token=23;
		//autentica o cara no LDAP e pega o diretorio raiz dele
		
		//propriedades
		Hashtable env = new Hashtable();
		
		String sp = "com.sun.jndi.ldap.LdapCtxFactory";
		env.put(Context.INITIAL_CONTEXT_FACTORY, sp);
		
		String ldapUrl = "ldap://127.0.0.1:389/dc=drop,dc=box";
		env.put(Context.PROVIDER_URL, ldapUrl);

		String authenticationType = "simple";
		env.put(Context.SECURITY_AUTHENTICATION, authenticationType);

		String principal = "cn=admin,dc=drop,dc=box";
		env.put(Context.SECURITY_PRINCIPAL, principal);

		String passwd = "tbmtbm";
		env.put(Context.SECURITY_CREDENTIALS, passwd);


		try{
			String pass="";
			DirContext dctx = new InitialDirContext(env);
			String base = "ou=people";
			SearchControls sc = new SearchControls();
			String[] attributeFilter = { "cn", "userPassword" };
			sc.setReturningAttributes(attributeFilter);
			sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
			String filter = "(cn="+user+")";
			NamingEnumeration results = dctx.search(base, filter, sc);
			boolean flag = true;
			boolean ever=true;
			for(;ever;){
				if (results.hasMore()) {
					SearchResult sr = (SearchResult) results.next();
					Attributes attrs = sr.getAttributes();
					Attribute attr = attrs.get("userPassword");
					pass=new String((byte[])(attr.get()));
					//homePath = attrs.get("homePath").get().toString();
					if (pass.equals(password)){
						flag=false;
						break;
					}
				}
				else
					break;
			}
			dctx.close();
			if (flag) //Se errou usuario ou senha
				out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerLogin><status>0</status></answerLogin>");
			else{ // se acertou
				ever=true;
				try{
					for(;ever;){
						token = 2+(int)(Math.random()*10000);
						if (!sessions.isValid(Integer.toString(token))){								//cria sessao
							sessions.createSession(Integer.toString(token),user,homePath);
							break;
						}
					}
					out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerLogin><status>"+token+"</status></answerLogin>");
				}
				catch (Exception e){
// 					out.println("lascou");
					out.println("Causa: "+e.getCause()+" Message: "+e.getMessage());
					for(int num=0;num<=e.getStackTrace().length-1;num++)
						out.println("File: "+e.getStackTrace()[num].getFileName()+" Classe: "+e.getStackTrace()[num].getClassName()+" Method: "+e.getStackTrace()[num].getMethodName()+" line:"+e.getStackTrace()[num].getLineNumber());
				}
			}
		}
		catch (Exception e){
			out.println("Causa: "+e.getCause()+" Message: "+e.getMessage());
			for(int num=0;num<=e.getStackTrace().length-1;num++)
				out.println("File: "+e.getStackTrace()[num].getFileName()+" Classe: "+e.getStackTrace()[num].getClassName()+" Method: "+e.getStackTrace()[num].getMethodName()+" line:"+e.getStackTrace()[num].getLineNumber());
		}
	}

	public void desconectar(){
		try{
			String token=request.getParameter("token");
			if (isAutenticated()){
					out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerLogoff><status>0</status></answerLogoff>");
					sessions.removeSession(token);
					return;
			}
			out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerLogoff><status>1</status></answerLogoff>");
		}
		catch (Exception e){
			out.print("lascou");
		}
	}

	public void download(){	//TODO
// 		boolean isAutenticated = isAutenticated(); //Verifica se esta autenticado
// 		String token=request.getParameter("token");
// 		String name=request.getParameter("name");
// 		String path=request.getParameter("path");
// 		if (!isAutenticated) //Se nao estiver manda xml reportando
// 			out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerDownload><file><name>"+name+"</name><path>"+path+"</path><status>1</status></file></answerDownload>");
// 		else{ //Se estiver
// 			//pego arquivo da camada de replicacao
// 			if (/*o arquivo nao existir*/)
// 				out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerDownload><file><name>"+name+"</name><path>"+path+"</path><status>2</status></file></answerDownload>");
// 			else{
// 			}
// 			if (/*o cara nao tiver permissao*/)
// 				out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerDownload><file><name>"+name+"</name><path>"+path+"</path><status>3</status></file></answerDownload>");
// 			else{
// 				if (/*qq outro erro*/)
// 					out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerDownload><file><name>"+name+"</name><path>"+path+"</path><status>4</status></file></answerDownload>");
// 				else{ /*se tudo der certo*/
// 					int port;
// 					boolean ever=true;
// 					ServerSocket serverSocket;
// 					for(;ever;){
// 						port = 2000+(int)( Math.random()*48000); //escolhe uma porta que nao esta sendo usada pra mandar o arquivo
// 						try {
// 							serverSocket = new ServerSocket(port,path,name);
// 							break;
// 						}
// 						catch (IOException e) 
// 							System.out.println("Could not listen on port: "+port);
// 						
// 					}
// 					new DownloadThread(serverSocket).start();
// 					out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerDownload><file><name>"+name+"</name><size>"+/*tamanho do arquivo*/+"</size><path>"+path+"</path><port>"+port+"</port><status>0</status></file></answerDownload>");
// 				}
// 			}
// 		}
	}

	public void upload(){
// 		boolean isAutenticated = isAutenticated();
// 		String token=request.getParameter("token");
// 		String name=request.getParameter("name");
// 		String path=request.getParameter("path");
// 		String version=request.getParameter("version");
// 		if (!isAutenticated) //Se nao estiver manda xml reportando
// 			out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerDownload><file><name>"+name+"</name><path>"+path+"</path><status>1</status></file></answerDownload>");
// 		else{ //Se estiver
// 			/*manda criar/atualizar o arquivo path/name com versao version*/
// 			if (/*versao for menor ou igual a do servidor*/){
// 				out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?><answerUpdate><path>"+path+"</path><name>"+name+"</name><version>"+version+"</version><status>2</status></answerUpdate>");
// 			}
// 			else{
// 				out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
// 						   <answerUpdate> \
// 								<path>"+path+"</path> \
// 								<name>"+name+"</name> \
// 								<version>"+version+"</version> \
// 						   <status>0</status></answerUpdate>");
// 			}
// 		}
	}
	
	/**
     * 0 - Sucesso              public static final int LIST_SUCESS 0
	 * 1 - Não está logado      public static final int LIST_NOT_LOGGED 1
	 * 2 - Fracasso genérico    public static final int LIST_ERROR 2
	 */
	public void listar(){
		String path = request.getParameter("path");
  		int status = 0; //LIST_SUCESS
  		ArrayList listFiles = new ArrayList();
	    
        //TODO: Como deveria ser...
  		/*boolean isAutenticated = isAutenticated();
  		
        if (isAutenticated) {
            //uma variável que recebe uma resposta da replicacao
            listFiles = replicao.list(path);

	    } else {
	        //alguma notificacao... ou não =p
	        status = LIST_ERROR;
	    }*/

	    String xml = 
	        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + NEWLINE +
            "<answerList>" + NEWLINE;
            /*for (int i = 0; i < listFiles.size(); i++) {
                Object obj = listFiles.get(i);
                
                if (obj instanceof File) {
                    xml += 
                    TAB + "<name>" + ((File) obj).getName() + "</name>" + NEWLINE +
            	    TAB + "<size>" + ((File) obj).getSize() + "</size>" + NEWLINE +
            	    TAB + "<version>" + ((File) obj).getVersion() + "</version>" + NEWLINE;
                } else if (obj instanceof Folder) {
                    xml += 
                    TAB + "<name>" + ((Folder) obj).getName() + "</name>" + NEWLINE +
            	    TAB + "<size>" + ((Folder) obj).getSize() + "</size>" + NEWLINE +
            	    TAB + "<itens>" + ((Folder) obj).getItens() + "</itens>" + NEWLINE;
                }
                
                xml += NEWLINE;
    	    }*/
            xml += "</answerList>";
            
        out.println(xml);
	}

    /**
     * 0 - Sucesso              public static final int MOVE_SUCESS 0
	 * 1 - Não está logado      public static final int MOVE_NOT_LOGGED 1
	 * 2 - Fracasso genérico    public static final int MOVE_ERROR 2
	 */
	public void mover(){
		String oldPath = request.getParameter("oldPath");
		String oldName = request.getParameter("oldName");
		String newPath = request.getParameter("newPath");
		String newName = request.getParameter("newName");
  		int status = 0; //MOVE_SUCESS
	    
        //TODO: Como deveria ser...
  		/*boolean isAutenticated = isAutenticated();
  		
        if (isAutenticated) {
            //uma variável que recebe uma resposta da replicacao
            status = replicao.move(oldPath, oldName, newPath, newName);

	    } else {
	        //alguma notificacao... ou não =p
	        status = MOVE_ERROR;
	    }*/

	    String xml = 
	        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + NEWLINE +
            "<answerMove>" + NEWLINE +
            TAB + "<oldPath>" + oldPath + "</oldPath>" + NEWLINE +
    	    TAB + "<oldName>" + oldName + "</oldName>" + NEWLINE +
    	    TAB + "<newPath>" + newPath + "</oldPath>" + NEWLINE +
    	    TAB + "<newName>" + newName + "</oldName>" + NEWLINE +
            TAB + "<status>" + status + "</status>" + NEWLINE +
            "</answerMove>";
            
        out.println(xml);
	}

    /**
     * 0 - Sucesso              public static final int DELETE_SUCESS 0
	 * 1 - Não está logado      public static final int DELETE_NOT_LOGGED 1
	 * 2 - Fracasso genérico    public static final int DELETE_ERROR 2
	 */
	public void deletar(){
		String path = request.getParameter("path");
		String name = request.getParameter("name");
  		int status = 0; //DELETE_SUCESS
	    
        //TODO: Como deveria ser...
  		/*boolean isAutenticated = isAutenticated();
  		
        if (isAutenticated) {
            //uma variável que recebe uma resposta da replicacao
            status = replicao.delete(path, name);

	    } else {
	        //alguma notificacao... ou não =p
	        status = DELETE_ERROR;
	    }*/

	    String xml = 
	        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + NEWLINE +
            "<answerDelete>" + NEWLINE +
            TAB + "<path>" + path + "</path>" + NEWLINE +
    	    TAB + "<name>" + name + "</name>" + NEWLINE +
            TAB + "<status>" + status + "</status>" + NEWLINE +
            "</answerDelete>";
            
        out.println(xml);
	}
	
    /**
     * 0 - Sucesso              public static final int MKDIR_SUCESS 0
	 * 1 - Não está logado      public static final int MKDIR_NOT_LOGGED 1
	 * 2 - Fracasso genérico    public static final int MKDIR_ERROR 2
	 */
	public void mkdir(){
		String path = request.getParameter("path");
		String name = request.getParameter("name");
  		int status = 0; //MKDIR_SUCESS
  		
		//apenas testando
		/*String path = request.getParameter("path");
		String name = request.getParameter("name");
		
	    File file = new File(path + File.separator + name);
	    out.println("criou o arquivo? - "+file.getAbsolutePath());
	    out.println("criou o arquivo? - "+file.mkdirs());*/
	    
        //TODO: Como deveria ser...
  		/*boolean isAutenticated = isAutenticated();
  		
        if (isAutenticated) {
            //uma variável que recebe uma resposta da replicacao
            status = replicao.mkdir(path, name);

	    } else {
	        //alguma notificacao... ou não =p
	        status = MKDIR_ERROR;
	    }*/
	    
	    String xml = 
	        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + NEWLINE +
            "<answerCreateFolder>" + NEWLINE +
            TAB + "<path>" + path + "</path>" + NEWLINE +
    	    TAB + "<name>" + name + "</name>" + NEWLINE +
            TAB + "<status>" + status + "</status>" + NEWLINE +
            "</answerCreateFolder>";
            
        out.println(xml);
	}

    /**
     * 0 - Sucesso              public static final int COPY_SUCESS 0
	 * 1 - Não está logado      public static final int COPY_NOT_LOGGED 1
	 * 2 - Fracasso genérico    public static final int COPY_ERROR 2
	 */
	public void copiar() {
        String path = request.getParameter("path");
		String name = request.getParameter("name");
		String copyPath = request.getParameter("copyPath");
  		int status = 0; //COPY_SUCESS
	    
        //TODO: Como deveria ser...
  		/*boolean isAutenticated = isAutenticated();
  		
        if (isAutenticated) {
            //uma variável que recebe uma resposta da replicacao
            status = replicao.copy(path, name, copyPath);

	    } else {
	        //alguma notificacao... ou não =p
	        status = COPY_ERROR;
	    }*/

	    String xml = 
	        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + NEWLINE +
            "<answerCopy>" + NEWLINE +
            TAB + "<path>" + path + "</path>" + NEWLINE +
    	    TAB + "<name>" + name + "</name>" + NEWLINE +
    	    TAB + "<copyPath>" + copyPath + "</copyPath>" + NEWLINE +
            TAB + "<status>" + status + "</status>" + NEWLINE +
            "</answerCopy>";
            
        out.println(xml);
	}

	public void atualizar(){
		boolean isAutenticated = isAutenticated();
	}

	public void versao(){
		boolean isAutenticated = isAutenticated();
	}

	public void versaoDisco(){
		boolean isAutenticated = isAutenticated();
	}
	
} 

